package com.cskaoyan.javase.thread._4synchronized._0introduction;

/**
 * 现在开发一个软件，模拟某影院售票窗口售票服务，要求如下：
 *      1.一共只卖100张票。
 *      2.影院有三个售票窗口，同时卖票，互不影响。
 * 方式二实现多线程环境下数据的共享
 *
 * 这种在多线程环境下，由于多线程间数据共享带来的数据失真，数据不合理的情况就是多线程的数据安全问题。
 *
 * 总结下来，之所以产生数据安全问题，就是三点：
 * 多线程下的程序运行特点导致。
 * 多线程下的线程共享数据需求导致。
 * 某个线程在执行一个需要访问共享数据任务的任意过程中，都有可能发生线程切换，其余线程也会执行这个任务。
 *
 * 为了解决数据安全问题,需要从第三点出发:
 * 只需要保证某个线程在执行售票操作的过程中,其它线程禁止去执行售票操作,于是就能够保证数据安全.
 * 在操作系统层面上，我们把一个不可分割的、要么全部执行，要么全部不执行的操作称之为“原子操作”。
 * 我们可以用原子操作的思想来解决数据安全问题。
 *
 * @since 14:58
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class TypeTwoImpl {
    public static void main(String[] args) {
        SellTicketTask task = new SellTicketTask();
        Thread t1 = new Thread(task, "窗口1");
        Thread t2 = new Thread(task, "窗口2");
        Thread t3 = new Thread(task, "窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}

class SellTicketTask implements Runnable {
    private int ticketNum = 1;

    @Override
    public void run() {
        while (ticketNum <= 100) {
            // 每次卖出一张票,休眠一段时间,模拟卖票需要耗费一点时间
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "卖出了第" + ticketNum + "张票!");
            ticketNum++;
        }
    }
}